﻿using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yozeev.BusinessLogic;
using Yozeev.BusinessLogic.Stats.Dtos;
using Yozeev.Common;
using Yozeev.Controllers.Stats.Filters;

namespace Yozeev.Controllers.CheckTicket
{
    /// <summary>
    /// 过闸统计
    /// </summary>
    [Route("api/CheckTicket/[Controller]/[Action]")]
    public class HistoryController: YozeevControllerBase
    {
        private readonly IRepository<GateRecord, Guid> _gateRecordRepository;

        private readonly IRepository<Device, Guid> _deviceRepository;

        private readonly IRepository<TicketDetailHistory, Guid> _ticketDetailHisRep;

        private readonly AbstractFilter _deviceFilter;

        private readonly AbstractFilter _checkerFilter;

        private readonly AbstractFilter _ticketFilter;

        private readonly IQueryHelper _queryHelper;

        public HistoryController(IRepository<GateRecord, Guid> gateRecordRepository, 
            IQueryHelper queryHelper, IRepository<Device, Guid> deviceRepository,
            IRepository<TicketDetailHistory, Guid> ticketDetailHisRep,
            DeviceFilter deviceFilter,
            CheckerFilter checkerFilter,
            TicketTypeFilter ticketFilter)
        {
            _gateRecordRepository = gateRecordRepository;
            _deviceRepository = deviceRepository;
            _ticketDetailHisRep = ticketDetailHisRep;
            _deviceFilter = deviceFilter;
            _checkerFilter = checkerFilter;
            _ticketFilter = ticketFilter;
            _queryHelper = queryHelper;
        }

        /// <summary>
        /// 过闸统计
        /// </summary>
        /// <param name="input"></param>
        /// <param name="ticketId">票型ID</param>
        /// <param name="scheduleId">航班ID</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PagedResultDto<GateHistoryResultDto>> GetPagedStat(GateHistoryInput input, string ticketId, string scheduleId)
        {
            var query = _gateRecordRepository.GetAll()
                .Where(_queryHelper.WhereExp<GateRecord>(input.queryData));

            if (!string.IsNullOrEmpty(ticketId))
            {
                var deviceIds = _ticketDetailHisRep.GetAll()
                    .Where(t => t.TicketId.ToString().Equals(ticketId))
                    .Select(t => t.DeviceId)
                    .ToList();
                query = query.Where(r => deviceIds.Contains(r.DeviceId));
            }

            if (!string.IsNullOrEmpty(scheduleId))
            {
                var deviceIds = _ticketDetailHisRep.GetAll()
                    .Where(t => t.TicketDetail.ScheduleId.ToString().Equals(scheduleId))
                    .Select(t => t.DeviceId)
                    .ToList();
                query = query.Where(r => deviceIds.Contains(r.DeviceId));
            }

            IQueryable<GateHistoryResultDto> result = 
                from gateRecord in query
                join sub in (
                    from gateRecord in query
                    group gateRecord by new { gateRecord.VerifiableType, gateRecord.DeviceId } into g
                    select new { VerifiableType = g.Key.VerifiableType, DeviceId = g.Key.DeviceId, Number = g.Count() }
                ) on new { gateRecord.VerifiableType, gateRecord.DeviceId } equals new { sub.VerifiableType, sub.DeviceId } into single
                join total in (
                    from gateRecord in query
                    group gateRecord by new { Deviceid = gateRecord.DeviceId } into t
                    select new { DeviceId = t.Key.Deviceid, Total = t.Count() }
                ) on gateRecord.DeviceId equals total.DeviceId
                join device in _deviceRepository.GetAll().Where(d => d.IsEnabled)
                on gateRecord.DeviceId equals device.Id
                orderby gateRecord.CreationTime descending
                select new GateHistoryResultDto
                {
                    DeviceId = gateRecord.DeviceId.ToString(),
                    DeviceName = device.DeviceName,
                    Total = total.Total,
                    VerifyTypeDatas = single.Select(s => new VerifyTypeDataItem
                    {
                        TypeName = s.VerifiableType.ToString(),
                        Value = s.Number
                    }).ToList()
                };

            var count = result.Count();
            Dictionary<string, IEnumerable<object>> filters = new Dictionary<string, IEnumerable<object>>();
            _ticketFilter.Decorate(filters);
            _checkerFilter.Decorate(filters);
            _deviceFilter.Decorate(filters);

            return new PagedResultDto<GateHistoryResultDto>(count, result.ToList());
        }
    }
}
